/* //device/system/broncho-ril/reference-ril.c
**
** Copyright 2006, The Android Open Source Project
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
**
**     http://www.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
*/

#include <telephony/ril.h>
#include <stdio.h>
#include <assert.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <pthread.h>
#include <alloca.h>
#include "atchannel.h"
#include "at_tok.h"
#include "ril_util.h"
#include <getopt.h>
#include <sys/socket.h>
#include "broncho-ril.h"
#include "ril-sim.h"

#define LOG_TAG "RIL"
#include "broncho_log.h"

static void requestSetMute(RIL* thiz, void *data, size_t datalen, RIL_Token t)
{
	char cmd[32] = {0};
	int mute = ((int*)data)[0];

	snprintf(cmd, 32, "AT+CMUT=%d", mute);

	ril_send_command(thiz, cmd, NULL);
	RIL_onRequestComplete(thiz, t, RIL_E_SUCCESS, NULL, 0);

	return;
}

static void requestOemHookStrings(RIL* thiz, void *data, size_t datalen, RIL_Token t)
{
	RIL_onRequestComplete(thiz, t, RIL_E_SUCCESS, data, datalen);

	return;
}

static void requestOemHookRaw(RIL* thiz, void *data, size_t datalen, RIL_Token t)
{
	RIL_onRequestComplete(thiz, t, RIL_E_SUCCESS, data, datalen);
}

static void reqestQueryAvailableBandMode(RIL* thiz, void* data, size_t datalen, RIL_Token t)
{
	int bands[] = {0, 1, 2, 4, 5, 6};

	RIL_onRequestComplete(thiz, t, RIL_E_SUCCESS, bands, sizeof (bands));

	return;
}

static void requestSetBandMode(RIL* thiz, void* data, size_t datalen, RIL_Token t)
{
	int mode = 0;
	char cmd[32] = {0};
	int bands[] = {3, 3, 5, -1, 3, 3, 12};

	mode = ((int *)data)[0];

	snprintf (cmd, 32, "AT+CPBSE=%d", bands[mode]);
	if (ril_command_exec_for_result(thiz, cmd))
	{
		RIL_onRequestComplete(thiz, t, RIL_E_SUCCESS, NULL, 0);
	}
	else
	{
		RIL_onRequestComplete(thiz, t, RIL_E_GENERIC_FAILURE, NULL, 0);
	}

	return;
}

static void requestBasebandVersion(RIL* thiz, void* data, size_t datalen, RIL_Token t)
{
	ATResponse *p_response = NULL;
	if (!ril_command_exec_singleline_for_result(thiz, "AT+CGMR", "+CGMR:", &p_response))
	{
        RIL_onRequestComplete(thiz, t, RIL_E_GENERIC_FAILURE, NULL, 0);
    } 
	else 
	{
		char* version = NULL;

		at_line_scanf_string (p_response->p_intermediates->line, &version);
		RIL_onRequestComplete(thiz, t, RIL_E_SUCCESS,
				version, sizeof(char *));
    }
    at_response_free(p_response);
	
	return;
}

static void requestGetMute(RIL* thiz, void *data, size_t datalen, RIL_Token t)
{
	int mute = 0;
	int result = 0;
	ATResponse *p_response = NULL;

	if(ril_command_exec_singleline_for_result(thiz, "AT+CMUT?", "+CMUT:", &p_response))
	{
		result = at_line_scanf_int(p_response->p_intermediates->line, &mute);
	}
	
	if (result)
	{
		RIL_onRequestComplete(thiz, t, RIL_E_SUCCESS, &mute, sizeof(mute));
	}
	else
	{
		RIL_onRequestComplete(thiz, t, RIL_E_GENERIC_FAILURE, NULL, 0);
	}
	at_response_free (p_response);

	return;
}

static void requestGetImeiSv(RIL* thiz, void *data, size_t datalen, RIL_Token t)
{
	ATResponse* p_response = NULL;

	if(ril_command_exec_singleline_for_result(thiz, "AT+EGMR=0,9", "+EGMR:", &p_response))
	{
		char* sv = NULL;

		at_line_scanf_string(p_response->p_intermediates->line, &sv);
		RIL_onRequestComplete(thiz, t, RIL_E_SUCCESS, sv, sizeof(char*));
	}
	else
	{
		RIL_onRequestComplete(thiz, t, RIL_E_GENERIC_FAILURE, NULL, 0);
	}
	at_response_free (p_response);

	return;
}

static void requestGetImei(RIL* thiz, void *data, size_t datalen, RIL_Token t)
{
	ATResponse *p_response = NULL;
	int err = 0;
	
	if(ril_command_exec_singleline_for_result(thiz, "AT+CGSN", "+CGSN:", &p_response))
	{
		char* imei = NULL;

		at_line_scanf_string(p_response->p_intermediates->line, &imei);
		RIL_onRequestComplete(thiz, t, RIL_E_SUCCESS, imei, sizeof(char*));
	}
	else
	{
		RIL_onRequestComplete(thiz, t, RIL_E_GENERIC_FAILURE, NULL, 0);
	}
    at_response_free(p_response);
	
	return;
}

static int isRadioOn (RIL* thiz)
{
	int radio_on = 0;
	ATResponse *p_response = NULL;

	if (ril_command_exec_singleline_for_result(thiz, "AT+CFUN?", "+CFUN:", &p_response))
	{
		at_line_scanf_int (p_response->p_intermediates->line, &radio_on);
	}
	at_response_free(p_response);

	return radio_on == 1;
}

static void requestResetRadio(RIL* thiz, void *data, size_t datalen, RIL_Token t)
{
	int result = 0;
	int simState = RIL_getSIMStatus(thiz);

	if(simState == RIL_SIM_PIN
		|| simState == RIL_SIM_PUK)
	{
		RIL_onRequestComplete(thiz, t, RIL_E_GENERIC_FAILURE, NULL, 0);
		return;
	}

	ril_command_exec_for_result(thiz, "ATH");
	if (ril_command_exec_full_for_result(thiz, "AT+CFUN=0", 20000))
	{
		RIL_SetRadioState(thiz, RADIO_STATE_OFF);
		if (ril_command_exec_full_for_result(thiz, "AT+CFUN=1", 20000))
		{
			RIL_SetRadioState(thiz, RADIO_STATE_SIM_NOT_READY);
			result = 1;
		}
	}

	if (result)
	{
		RIL_onRequestComplete(thiz, t, RIL_E_SUCCESS, NULL, 0);
	}
	else
	{
		RIL_onRequestComplete(thiz, t, RIL_E_GENERIC_FAILURE, NULL, 0);
	}

	return;
}

static void requestRadioPower(RIL* thiz, void *data, size_t datalen, RIL_Token t)
{
    int onOff = 0;
	int State = 0;
	int success = 1;

    assert (datalen >= sizeof(int *));
    onOff = ((int *)data)[0];
	
	State = RIL_GetState(thiz);
    if (onOff == 0 && State != RADIO_STATE_OFF)// && isRadioOn(thiz)) 
	{
		ril_command_exec_for_result(thiz, "ATH");
		
		/*broncho modify by yinlijun for zte bug*/
		ril_command_exec_full_for_result(thiz, "AT+CFUN=0", 20000);
		RIL_SetRadioState(thiz, RADIO_STATE_OFF);
		success = 1;
		/*
		if(success = ril_command_exec_full_for_result(thiz, "AT+CFUN=0", 20000))
		{
			RIL_SetRadioState(thiz, RADIO_STATE_OFF);
		}
		*/
    } 
	else if (onOff > 0 && State == RADIO_STATE_OFF)// && !isRadioOn(thiz)) 
	{
		if(success = ril_command_exec_full_for_result(thiz, "AT+CFUN=1", 20000))
		{
	    	RIL_SetRadioState(thiz, RADIO_STATE_SIM_NOT_READY);
		}
    }

	if (success)
	{
    	RIL_onRequestComplete(thiz, t, RIL_E_SUCCESS, NULL, 0);
	}
	else
	{
		RIL_onRequestComplete(thiz, t, RIL_E_GENERIC_FAILURE, NULL, 0);
	}

	return;
}

/*
static void requestRadioPower(RIL* thiz, void *data, size_t datalen, RIL_Token t)
{
    int onOff = 0;
	int State = 0;
	int success = 1;
	static int first = 1;

    assert (datalen >= sizeof(int *));
    onOff = ((int *)data)[0];
	ALOGD("!!!first:%d", first);
	State = RIL_GetState(thiz);
    if (onOff == 0 && State != RADIO_STATE_OFF)// && isRadioOn(thiz)) 
	{
		ril_command_exec_for_result(thiz, "ATH");
		
		if(first == 0)
		{	
			success = ril_command_exec_full_for_result(thiz, "AT+CFUN=0", 20000);  
			if(!success)  
			{	
				RIL_onRequestComplete(thiz, t, RIL_E_GENERIC_FAILURE, NULL, 0);
				
				return;
			}
		}
		first = 0;
		RIL_SetRadioState(thiz, RADIO_STATE_OFF);
    } 
	else if (onOff > 0 && State == RADIO_STATE_OFF)// && !isRadioOn(thiz)) 
	{
		success = ril_command_exec_full_for_result(thiz, "AT+CFUN=1", 20000);
		if(!success)
		{
			if(!isRadioOn(thiz)) 
			{
				RIL_onRequestComplete(thiz, t, RIL_E_GENERIC_FAILURE, NULL, 0);
				
				return;
			}
		}
	    RIL_SetRadioState(thiz, RADIO_STATE_SIM_NOT_READY);
    }

	if (success)
	{
    	RIL_onRequestComplete(thiz, t, RIL_E_SUCCESS, NULL, 0);
	}
	else
	{
		RIL_onRequestComplete(thiz, t, RIL_E_GENERIC_FAILURE, NULL, 0);
	}

	return;
}
*/

int RIL_initialize_dev (RIL* thiz)
{
	/* broncho modify by yinliju */
	//ril_send_command(thiz, "AT+CMER=3,0,0,1,0", NULL);
	//ril_send_command(thiz, "AT+CMER=3,0,0,2,0", NULL);
	/* broncho modify end */
	/* broncho delete by yinlijun */
	//ril_send_command(thiz, "AT^CVOICE=2", NULL);	
	//ril_send_command(thiz, "AT+CLVL=4", NULL);
	/* broncho delete end */
	return 1;
}

int RIL_onUnsolicited_dev (RIL* thiz, const char* s)
{
	int ret = 0;

	return ret;
}

int RIL_onRequest_dev (RIL* thiz, int request, void *data, size_t datalen, RIL_Token t)
{
	/*
	ALOGD(">>>>>>>>>>>>>>>>>>>>>>>>");
    ril_command_exec_full_for_result(thiz, "AT+CFUN=0", 20000);
    ril_command_exec_full_for_result(thiz, "AT+CFUN=1", 20000);
    ALOGD("<<<<<<<<<<<<<<<<<<<<<<<<");
	*/
	switch (request)
	{
	case RIL_REQUEST_RADIO_POWER:
		requestRadioPower(thiz, data, datalen, t);
		break;

	case RIL_REQUEST_GET_IMEI:
		requestGetImei(thiz, data, datalen, t);
		break;

	case RIL_REQUEST_GET_IMEISV:
		requestGetImeiSv(thiz, data, datalen, t);
		break;

	case RIL_REQUEST_SET_MUTE:
		requestSetMute(thiz, data, datalen, t);
		break;

	case RIL_REQUEST_GET_MUTE:
		requestGetMute(thiz, data, datalen, t);
		break;

	case RIL_REQUEST_RESET_RADIO:
		requestResetRadio(thiz, data, datalen, t);
		break;

	case RIL_REQUEST_BASEBAND_VERSION:
		requestBasebandVersion(thiz, data, datalen, t);
		break;

	case RIL_REQUEST_SET_BAND_MODE:
		requestSetBandMode(thiz, data, datalen, t);
		break;

	case RIL_REQUEST_QUERY_AVAILABLE_BAND_MODE:
		reqestQueryAvailableBandMode(thiz, data, datalen, t);
		break;

	case RIL_REQUEST_OEM_HOOK_RAW:
		requestOemHookRaw(thiz, data, datalen, t);
		break;

	case RIL_REQUEST_OEM_HOOK_STRINGS:
		requestOemHookStrings(thiz, data, datalen, t);
		break;

	default:
		RIL_onRequestComplete(thiz, t, RIL_E_REQUEST_NOT_SUPPORTED, NULL, 0);
		break;
	}

	return 1;
}


